package views
{   
	import Events.*;
	
	import caurina.transitions.Tweener;
	
	import com.lib.playbook.dialog.DialogBase;
	import com.lib.playbook.events.DialogEvent;
	import com.oosterwijk.irc.FlexIrcClient;
	import com.oosterwijk.irc.User;
	import com.oosterwijk.irc.event.*;
	
	import flash.desktop.NativeApplication;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.net.SharedObject;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	
	import qnx.dialog.DialogSize;
	import qnx.dialog.PromptDialog;
	import qnx.display.*;
	import qnx.ui.buttons.LabelButton;
	import qnx.ui.core.*;
	import qnx.ui.data.DataProvider;
	import qnx.ui.listClasses.DropDown;
	import qnx.ui.text.Label;
	import qnx.ui.text.TextInput;

	public class MenuBar extends Sprite
	{
		public static const WIDTH:int = 1024;
		public static const HEIGHT:int = 250;
		public static const VISIBLE_Y:int = 0;
		public static const HIDDEN_Y:int = -HEIGHT;
		public static const SLIDE_TIME:Number = 0.5;
		/* the Flex IRC Client Object */
		private var _flexIrcClient:FlexIrcClient = null;
		
		private var _clientApp:IRCClientApp;
		private var _active:Boolean;
		
		private var _serverDP:DropDown;
		private var _connBT:LabelButton;
		private var _clBT:LabelButton;
		private var _editBT:LabelButton;
		private var _changeNick:LabelButton;
		private var _editServerDlg:EditServerDialog;
		private var _eventDispatcher:IEventDispatcher = new EventDispatcher();
		private var _configArr:Array = null;
		private var _nick:String = '';
		
		private var _joinTI:TextInput;
		private var _joinBT:LabelButton;
		private var _currentChannel:Label;
		private var _channelOpDP:DropDown;
		private var _channelOpArr:Array = [{label:"Part"}];
		
		private var _mainContainer:Container;
		private var _serverOptionContainer:Container;
		private var _channelOptionContainer:Container;
		
		private var _isPrivateChat:Boolean = false;
		
		private var _settingPrompt:PromptDialog = null;
		public function MenuBar()
		{
			initializeUI();
		}
		private function initializeUI():void
		{
			_active = false;
			
			NativeApplication.nativeApplication.addEventListener(Event.EXITING,appExit)
			var so:SharedObject = SharedObject.getLocal("irc");
			_configArr = so.data.array as Array;
			if(!_configArr){
				_configArr = [];
			}
			_nick = so.data.nick as String;
			if(!_nick){
				_nick = "Guest" + Math.round(Math.random()*1000);
			}
			// set default position (HIDDEN_Y)
			this.x = 0;
			this.y = HIDDEN_Y;
			this.graphics.beginFill(0x222222,0.7);
			this.graphics.drawRect(0,0,WIDTH,HEIGHT);
			this.graphics.endFill();

			_mainContainer = new Container();
			//_mainContainer.margins = Vector.<Number>([2,2,2,2]);
			_mainContainer.flow = ContainerFlow.VERTICAL;
			//_mainContainer.debugColor = 0xFFCC00;
			_mainContainer.padding = 10;
			
			_serverOptionContainer = new Container();
			_serverOptionContainer.flow = ContainerFlow.HORIZONTAL;
			_serverOptionContainer.sizeUnit = SizeUnit.PERCENT;
			_serverOptionContainer.containment = Containment.DOCK_TOP;
			_serverOptionContainer.align = ContainerAlign.MID;
			_serverOptionContainer.size = 50;
			

			_configArr.push({label: "Add new"});
			_serverDP = new DropDown();
			_serverDP.dataProvider = new DataProvider(_configArr);
			_serverOptionContainer.addChild(_serverDP);
			
			_connBT = new LabelButton();
			_connBT.label = "Connect";
			_connBT.addEventListener(MouseEvent.CLICK, onConnBT);
			_serverOptionContainer.addChild(_connBT);
			
			_editBT = new LabelButton();
			_editBT.label = "Edit";
			_editBT.addEventListener(MouseEvent.CLICK, onEditServer);
			_serverOptionContainer.addChild(_editBT);
			
			_changeNick = new LabelButton();
			_changeNick.label = "Change nick";
			_changeNick.addEventListener(MouseEvent.CLICK, onChangeNick);
			_serverOptionContainer.addChild(_changeNick);
			
			_clBT = new LabelButton();
			_clBT.label = "Channel list";
			_clBT.enabled = false;
			_clBT.addEventListener(MouseEvent.CLICK, onChannelList);
			_serverOptionContainer.addChild(_clBT);
			
			_mainContainer.addChild(_serverOptionContainer);
			
			_channelOptionContainer = new Container();
			_channelOptionContainer.flow = ContainerFlow.HORIZONTAL;
			_channelOptionContainer.sizeUnit = SizeUnit.PERCENT;
			//_channelOptionContainer.containment = Containment.
			_channelOptionContainer.align = ContainerAlign.MID;
			_channelOptionContainer.size = 50;
			
			var channelOpLbl:Label = new Label();
			channelOpLbl.text = "Current channel:";
			channelOpLbl.width = 150;
			var tf:TextFormat = new TextFormat();
			tf.color = "0xFFFFFF";
			channelOpLbl.format = tf;
			_channelOptionContainer.addChild(channelOpLbl);
			
			_currentChannel = new Label();
			_currentChannel.format = tf;
			_channelOptionContainer.addChild(_currentChannel);
			
			_channelOpDP = new DropDown();
			_channelOpDP.dataProvider = new DataProvider(this._channelOpArr);
			_channelOpDP.addEventListener(Event.SELECT, onChannelOp);
			_channelOptionContainer.addChild(_channelOpDP);

			_joinTI = new TextInput();
			_joinTI.width = 200;
			_joinTI.height = 40;
			_joinTI.text = '#';
			_channelOptionContainer.addChild(_joinTI);
			
			_joinBT = new LabelButton();
			_joinBT.label = "Join";
			_joinBT.addEventListener(MouseEvent.CLICK, onJoinBT);
			_channelOptionContainer.addChild(_joinBT);
			
			
			_mainContainer.addChild(_channelOptionContainer);
			
			
			this.addChild(_mainContainer);
			_mainContainer.setSize(1024, 250);
			
			_channelOptionContainer.visible = false;
			Events.SharedData.instance.addEventListener(UIEvent.CHANNEL_CHANGED, onUIChannelChanged);
		}
		
		public function isVisible():Boolean
		{
			return _active;
		}
		public function show():void
		{
			_active = true;
			Tweener.addTween(this, {y:VISIBLE_Y, time:SLIDE_TIME, transition:"easeOutExpo"});
			
		}
		public function hide():void
		{
			_active = false;
			Tweener.addTween(this, {y:HIDDEN_Y, time:SLIDE_TIME, transition:"linear"});
		}
		public function processEvent(event:MouseEvent):void
		{
			if(event.localY > HEIGHT)
			{
				hide();
			}
		}
		/**
		 * Public getter and setter for the IRC Client Connection Object
		 */
		public function get flexIrcClient():FlexIrcClient
		{
			return _flexIrcClient;  
		}
		public function set flexIrcClient(value:FlexIrcClient):void
		{
			_flexIrcClient = value;
		}
		
		public function setCallbackFunctions():void
		{
			flexIrcClient.setVerbose(true);
			flexIrcClient.addEventListener(FlexIrcClient.CONNECT_EVENT,this.onConnect);
			flexIrcClient.addEventListener(FlexIrcClient.DISCONNECT_EVENT,this.onDisconnect);
			flexIrcClient.addEventListener(FlexIrcClient.NICK_CHANGE_EVENT, onNickChange);
			flexIrcClient.setName(_nick);
		}
		
		private function onJoinBT(event:MouseEvent):void
		{
			if(_joinTI.text.length == 0 || _joinTI.text == '#' || !flexIrcClient.isConnected())
				return;
			flexIrcClient.joinChannel(_joinTI.text);
			dispatchMouseEvent();
		}
		
		private function onNickChange(event:UserEvent):void
		{
			if(!(event.sender == _nick)) return;
			_nick = event.newNick;
		}
		
		private function onChannelOp(event:Event):void
		{
			if(event.target.selectedIndex == 0 && flexIrcClient.isConnected()){
				if(!this._isPrivateChat)
					flexIrcClient.partChannel(_currentChannel.text);
				else{
					var evt:UIEvent = new UIEvent(UIEvent.CLOSE_PRIVATE_CHAT);
					evt.channel = _currentChannel.text;
					Events.SharedData.instance.dispatchEvent(evt);
				}
				dispatchMouseEvent();
			}
		}
		
		private function onUIChannelChanged(event:UIEvent):void
		{
			if(event.channel.length !=0){
				_currentChannel.text = event.channel;
				_channelOpDP.enabled = true;
			}
			else {
				_currentChannel.text = "none";
				_channelOpDP.enabled = false;
			}
			_isPrivateChat = event.isPrivate;
		}
		
		private function onConnect(event:IrcEvent):void
		{
			this._connBT.label = "Disconnect";
			this._editBT.enabled = false;
			this._clBT.enabled = true;
			//this._changeNick.enabled = false;
			this._serverDP.enabled = false;
			_channelOptionContainer.visible = true;
		}
		private function onDisconnect(event:IrcEvent):void
		{
			this._connBT.label = "Connect";
			this._editBT.enabled = true;
			//this._changeNick.enabled = true;
			this._clBT.enabled = false;
			this._serverDP.enabled = true;
			this._channelOptionContainer.visible = false;
		}
		private function onConnBT(event:MouseEvent):void
		{
			if(this._flexIrcClient.isConnected()){
				_flexIrcClient.disconnect();
			} else{
				if(_serverDP.selectedIndex < _serverDP.dataProvider.length -1){
					//_flexIrcClient.setName("Guest" + Math.round(Math.random()*1000));
					var obj:Object = _serverDP.dataProvider.getItemAt(_serverDP.selectedIndex);
					var port:int = parseInt(obj.port);
					var pass:String = obj.pass as String;
					_flexIrcClient.connect(obj.url, port, pass);
					_connBT.label = "Connecting...";
					dispatchMouseEvent();
				}
			}
			
		}
		
		private function onChangeNick(event:MouseEvent):void
		{
			_settingPrompt = new PromptDialog();
			_settingPrompt.title = "Nick name";
			_settingPrompt.message = "Please enter your nick name:";
			_settingPrompt.addButton("OK");
			_settingPrompt.addButton("Cancel");
			_settingPrompt.text = _nick;
			_settingPrompt.dialogSize= DialogSize.SIZE_SMALL;
			_settingPrompt.addEventListener(Event.SELECT, onPromptButton); 
			_settingPrompt.show(IowWindow.getAirWindow().group);
		}
		
		private function onPromptButton(event:Event):void
		{
			if(_settingPrompt.selectedIndex == 0){
				if(_settingPrompt.text == null || _settingPrompt.text.length == 0)
					return;
				if(_flexIrcClient.isConnected()){
					_flexIrcClient.changeNick(_settingPrompt.text);
				} else {
					_nick = _settingPrompt.text;
					_flexIrcClient.setName(_nick);
				}
			}
		}
		
		private function dispatchMouseEvent():void
		{
			var evt:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, false, false);
			evt.localX = 100;
			evt.localY = HEIGHT + 100;
			Events.SharedData.instance.dispatchEvent(evt);
		}
		protected function onChannelList(event:MouseEvent):void
		{
			_flexIrcClient.listChannels();
			dispatchMouseEvent();
		}
		protected function onEditServer(event:MouseEvent):void
		{
			if(!_editServerDlg)
				_editServerDlg = new EditServerDialog();
			
			_editServerDlg.hideOnClose = false;
			_editServerDlg.addEventListener(EditServerDialogEvent.DIALOG_CLOSED, onServerEdit);
			if(_serverDP.selectedIndex < _serverDP.dataProvider.length - 1){
				var obj:Object = _serverDP.dataProvider.getItemAt(_serverDP.selectedIndex);
				_editServerDlg.reset();
				_editServerDlg.networkName = obj.label;
				_editServerDlg.address = obj.url;
				_editServerDlg.port = obj.port;
				_editServerDlg.password = obj.pass;
				_editServerDlg.index = _serverDP.selectedIndex;
			} else {
				_editServerDlg.reset();
				_editServerDlg.index = _serverDP.selectedIndex;
			}
			
			_editServerDlg.show();
		}
		private function onServerEdit(event:DialogEvent):void
		{
			var evt:EditServerDialogEvent = event as EditServerDialogEvent;
			if(evt.del){
				if(evt.index == _serverDP.dataProvider.length -1){
					return;
				}
				_serverDP.dataProvider.removeItemAt(evt.index);
				return;
			}
			var obj:Object = new Object();
			obj.label = evt.networkName;
			obj.url = evt.address;
			obj.port = evt.port;
			obj.pass = evt.password;
			if(evt.index == _serverDP.dataProvider.length - 1){
				_serverDP.dataProvider.addItemAt(obj, evt.index);
			} else {
				_serverDP.dataProvider.replaceItemAt(obj, evt.index);
			}
			_serverDP.drawNow();
		}
		protected function appExit(e:Event):void{
			var so:SharedObject = SharedObject.getLocal("irc");
			var arr:Array = _serverDP.dataProvider.data;
			arr.pop();		// remove the last one "Add new"
			so.data.array = arr;
			so.data.nick = _nick;
			so.flush();
		}
	}
}